package modelo.geometria;

public class SegmentoRecta extends Figura {
	
	private Vector punto1;
	private Vector punto2;
	private boolean segmentoVertical;
	
	/*-- CONSTRUCTORES --*/
	
	public SegmentoRecta(Vector punto1, Vector punto2) {

		this.punto1 = punto1;
		this.punto2 = punto2;
		
		if (punto1.getX() == punto2.getX()) segmentoVertical = true; else segmentoVertical = false;
	}
	
	public Vector punto1() {
		return punto1;
	}
	
	public Vector punto2() {
		return punto2;
	}
	
	private double getPendiente(){
		return (punto2.getY() - punto2.getY()) / (punto2.getX() - punto1.getX());
	}
	
	private double getOrdenadaAlOrigen() {
		return punto1.getY() - getPendiente() * punto1.getX();
	}
	
	public boolean probarXEnRango(double x) {
		if (x >= punto1.getX() && x <= punto2.getX()) return true;
		return false;
	}
	
	public boolean probarYEnRango(double y){
		if (y >= punto1.getY() && y <= punto2.getY()) return true;
		return false;
	}
	
	public boolean probarPuntoPertenece(Vector punto) {
		if (!probarXEnRango(punto.getX())) return false;		
		if (punto.getY() == getY(punto.getX())) return true;
		return false;
	}
	
	public double getY(double x) {
		if (segmentoVertical) return punto1.getY();
		return x * getPendiente() + getOrdenadaAlOrigen();
	}
	
	public boolean intercepta(SegmentoRecta otroSegmento) {
		
		// si las dos rectas son verticales...
		if (segmentoVertical && otroSegmento.segmentoVertical)
			return probarPuntoPertenece(otroSegmento.punto1) || probarPuntoPertenece(otroSegmento.punto2) ||
				otroSegmento.probarPuntoPertenece(punto1); // optimizacion: no hace falta el ultimo... || otroSegmento.probarPuntoPertenece(punto2);
		
		// si la primera es vertical y la segunda no...
		if (segmentoVertical) {
			double xTemporal = punto1.getX();
			double yTemporal = otroSegmento.getPendiente() * xTemporal + otroSegmento.getOrdenadaAlOrigen();
			Vector puntoTemporal = new Vector(xTemporal,yTemporal);
			return probarPuntoPertenece(puntoTemporal) && otroSegmento.probarPuntoPertenece(puntoTemporal);
		}
		
		// si la segunda es vertical y la primera no...
		if (otroSegmento.segmentoVertical) {
			double xTemporal = otroSegmento.punto1.getX();
			double yTemporal = getPendiente() * xTemporal + getOrdenadaAlOrigen();
			Vector puntoTemporal = new Vector(xTemporal,yTemporal);
			return probarPuntoPertenece(puntoTemporal) && otroSegmento.probarPuntoPertenece(puntoTemporal);
		}
		
		
		// si ninguna es vertical, hay dos casos en que devuelve true:
		
		// 1) si las pendientes son iguales, al menos uno de los puntos extremos de uno tienen que pertenecer al otro 
		if	(this.getPendiente() == otroSegmento.getPendiente()) {
			return probarPuntoPertenece(otroSegmento.punto1) || probarPuntoPertenece(otroSegmento.punto2) ||
				otroSegmento.probarPuntoPertenece(punto1);
		}
		
		// 2) si las pendientes son distintas, las rectas se cruzan en un punto. Chequar si ese punto pertenece a los dos segmentos.
		
		double xTemporal = (getOrdenadaAlOrigen() - otroSegmento.getOrdenadaAlOrigen()) / (otroSegmento.getPendiente() - getPendiente());
		double yTemporal = getY(xTemporal);
		Vector puntoTemporal = new Vector(xTemporal,yTemporal);
		return probarPuntoPertenece(puntoTemporal) && otroSegmento.probarPuntoPertenece(puntoTemporal);
		
	}

	@Override
	public boolean solapa(SegmentoRecta segmentoRecta) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean solapa(Rectangulo rectangulo) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean solapa(Circunferencia circunferencia) {
		// devuelve si la circunferencia y el segmento se solapan
		Vector centroCircunferencia = circunferencia.getCentro();
		Vector vectorDiferenciaCircunferenciaSegmento = Vector.resta(centroCircunferencia, punto1);
		Vector vectorSegmento = Vector.resta(punto1, punto2);
		Vector vectorSegmentoRotado = Vector.traslacion( vectorSegmento, Math.PI /2 );
		Vector vectorSegmentoRotadoUnitario =  
			Vector.multiplicacion( vectorSegmentoRotado, 1 / vectorSegmentoRotado.getRho() );
		double distanciaCircunferenciaSegmento = 
			Math.abs(Vector.productoEscalar( vectorSegmentoRotadoUnitario, vectorDiferenciaCircunferenciaSegmento));
		if (distanciaCircunferenciaSegmento <= circunferencia.getRadio()) return true;
		return false;
	}

	@Override
	public Vector getCentro() {
		Vector vectorDiferencia = Vector.resta(punto1, punto2);
		Vector vectorDiferenciaMitad = Vector.multiplicacion(vectorDiferencia,0.5);
		Vector centro = Vector.suma(punto1, vectorDiferenciaMitad);
		return centro;
	}

	@Override
	public boolean solapa(Figura otraFigura) {
		otraFigura.solapa(this);
		return false;
	}

	@Override
	public Figura mover(final Vector nuevaPosicion) {
		// TODO Auto-generated method stub
		return this;
		
	}
}
